using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text;
using UMC.Net;

namespace UMC.Proxy
{

    abstract class WebSocket : UMC.Net.MimeRequest, IDisposable
    {
        public override bool IsWebSocket => true;
        public abstract void Dispose();
    }
    class HttpWebSocket : WebSocket
    {

        byte[] buffer = System.Buffers.ArrayPool<byte>.Shared.Rent(0x600);
        Socket socket;
        public HttpWebSocket(HttpMime mime, Socket stream)
        {
            this.mime = mime;
            this.socket = stream;
            SocketAsyncEventArgs eventArgs = new SocketAsyncEventArgs();
            eventArgs.SetBuffer(buffer);
            eventArgs.Completed += Http;
            if (!this.socket.ReceiveAsync(eventArgs))
            {
                ProcessReceive(eventArgs);
            }
        }
        HttpMime mime;

        private void Http(object sender, SocketAsyncEventArgs e)
        {
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Receive:
                    ProcessReceive(e);
                    break;
            }
        }
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                try
                {
                    this.mime.Write(buffer, e.Offset, e.BytesTransferred);
                    if (!socket.ReceiveAsync(e))
                    {
                        ProcessReceive(e);
                    }
                }
                catch
                {
                    this.Dispose();
                }
            }
            else
            {
                this.Dispose();
            }
        }

        public override void Receive(byte[] buffer, int offset, int size)
        {
            socket.Send(buffer, offset, size, SocketFlags.None);
        }
        protected override void Header(byte[] data, int offset, int size)
        {

        }
        public override void Dispose()
        {
            this.mime.Dispose();
            try
            {
                socket.Shutdown(SocketShutdown.Both);
            }
            catch
            {

            }
            socket.Close();
            if (buffer != null)
                System.Buffers.ArrayPool<byte>.Shared.Return(buffer);
            buffer = null;
        }
    }

}

